package com.zf.aliyun.sms.service;

import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.zf.aliyun.sms.config.AliyunSmsProperties;
import com.zf.aliyun.sms.constants.CommonConstants;
import com.zf.common.web.exception.BusinessException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * 邮件发送服务
 */
@Slf4j
@Service
public class AliyunSmsService {
    @Autowired
    private AliyunSmsProperties aliyunSmsProperties;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 发送短信验证码
     *
     * @param phone 手机号
     */
    @SneakyThrows
    public boolean sendMsgCode(String phone) {

        // 创建配置
        Config config = new Config();
        // 您的 AccessKey ID
        config.setAccessKeyId(aliyunSmsProperties.getAccessKeyId());
        // 您的 AccessKey Secret
        config.setAccessKeySecret(aliyunSmsProperties.getAccessKeySecret());
        // 阿里云短信API的地址
        config.setEndpoint(aliyunSmsProperties.getEndpoint());

        // 创建请求
        SendSmsRequest request = new SendSmsRequest();
        // 你申请的签名
        request.setSignName(aliyunSmsProperties.getSignName());
        // 你申请的模板code
        request.setTemplateCode(aliyunSmsProperties.getTemplateCode());
        // 给哪个手机号发送短信
        request.setPhoneNumbers(phone);

        // 构建短信验证码, 6位数字
        String codeNumber = randomString(6);

        // 将验证码写入redis, 5分钟后过期
        redisTemplate.opsForValue().set(CommonConstants.SMS_CODE_PREFIX + phone, codeNumber, 5, TimeUnit.MINUTES);

        // 设置模板中的参数，我是用的是测试模板，其中中有一个名为 code 的参数，传递json格式参数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", codeNumber);
        request.setTemplateParam(jsonObject.toString());

        // 创建客户端
        Client client = new Client(config);
        // 发送请求
        SendSmsResponse response = client.sendSms(request);
        // 发送成功或者失败
        if (Objects.equals("OK", response.getBody().getCode())) {
            return true;
        } else {
            throw new BusinessException(response.getBody().getMessage());
        }
    }

    /**
     * 校验验证码是否正确
     *
     * @param phone 手机号
     * @param code  验证码
     */
    public boolean verifyMsgCode(String phone, String code) {
        // 获取存储的验证码
        String key = CommonConstants.SMS_CODE_PREFIX + phone;
        String generateCode = String.valueOf(redisTemplate.opsForValue().get(key));
        boolean res = Objects.equals(generateCode, code);
        if (res) {
            // 校验正确，则删除验证码
            redisTemplate.delete(key);
        }
        return res;
    }

    public static String randomString(int length) {
        String baseString = "0123456789";
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; ++i) {
            int number = ThreadLocalRandom.current().nextInt(baseString.length());
            sb.append(baseString.charAt(number));
        }
        return sb.toString();
    }

}
